package message

import (
	"cloud_android_backend/pkg/utils"
	"context"
	"encoding/json"
	"fmt"
	openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
	dysmsapi20170525 "github.com/alibabacloud-go/dysmsapi-20170525/v3/client"
	util "github.com/alibabacloud-go/tea-utils/v2/service"
	"github.com/alibabacloud-go/tea/tea"
	"github.com/golang/glog"
	"k8s.io/klog/v2"
	"os"
	"strconv"
	"strings"
	"time"
)

const (
	PhoneVerifyCodeCacheName = "phone_code:"
)

type AliSMS struct {
	Client *dysmsapi20170525.Client
}

//NewAliSMS
/**
 * 使用AK&SK初始化账号Client
 * @param accessKeyId
 * @param accessKeySecret
 * @return *AliSMS
 * @throws Exception
 */
func NewAliSMS() *AliSMS {
	// 工程代码泄露可能会导致 AccessKey 泄露，并威胁账号下所有资源的安全性。以下代码示例仅供参考。
	// 建议使用更安全的 STS 方式，更多鉴权访问方式请参见：https://help.aliyun.com/document_detail/378661.html。
	config := &openapi.Config{
		// 必填，请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_ID。
		AccessKeyId: tea.String(os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_ID")),
		// 必填，请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_SECRET。
		AccessKeySecret: tea.String(os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET")),
	}
	fmt.Printf("access key:%s,access secret:%s", os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"), os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"))
	// Endpoint 请参考 https://api.aliyun.com/product/Dysmsapi
	config.Endpoint = tea.String("dysmsapi.aliyuncs.com")
	var _result *dysmsapi20170525.Client
	var _err error
	_result = &dysmsapi20170525.Client{}
	_result, _err = dysmsapi20170525.NewClient(config)
	fmt.Printf("%#v", _result)
	if _err != nil {
		glog.Errorf("get aliyun config failed:%s", _err.Error())
	}
	return &AliSMS{Client: _result}
}

func (a *AliSMS) SendPhoneCode(phone, code string) (_err error) {

	sendSmsRequest := &dysmsapi20170525.SendSmsRequest{
		PhoneNumbers:    tea.String(phone),
		SignName:        tea.String("湖南锦田科技"),
		TemplateCode:    tea.String("SMS_318905414"),
		TemplateParam:   tea.String("{\"code\":\"" + code + "\"}"),
		SmsUpExtendCode: tea.String(""),
	}
	fmt.Printf("send sms phone:%s", phone)
	runtime := &util.RuntimeOptions{}
	tryErr := func() (_e error) {
		//defer func() {
		//	if r := tea.Recover(recover()); r != nil {
		//		glog.Errorf("recover errors:%s", r.Error())
		//		_e = r
		//	}
		//}()
		// 复制代码运行请自行打印 API 的返回值
		response, _err := a.Client.SendSmsWithOptions(sendSmsRequest, runtime)
		fmt.Printf("response is kkk:%#v", response)
		if _err != nil {
			glog.Errorf("SendSmsWithOptions falied:%s", _err.Error())
			return _err
		}
		redisCli := utils.GetRedis()
		redisCli.HSet(context.Background(), PhoneVerifyCodeCacheName+phone, map[string]string{
			"code":      code,
			"send_time": strconv.FormatInt(time.Now().Unix(), 10),
		})
		redisCli.Expire(context.Background(), PhoneVerifyCodeCacheName+phone, time.Minute*5)
		return
	}()

	if tryErr != nil {
		var error = &tea.SDKError{}
		if _t, ok := tryErr.(*tea.SDKError); ok {
			error = _t
		} else {
			error.Message = tea.String(tryErr.Error())
		}
		// 此处仅做打印展示，请谨慎对待异常处理，在工程项目中切勿直接忽略异常。
		// 错误 message
		fmt.Println(tea.StringValue(error.Message))
		// 诊断地址
		var data interface{}
		d := json.NewDecoder(strings.NewReader(tea.StringValue(error.Data)))
		d.Decode(&data)
		if m, ok := data.(map[string]interface{}); ok {
			recommend, _ := m["Recommend"]
			fmt.Println(recommend)
		}
		_, _err = util.AssertAsString(error.Message)
		if _err != nil {
			return _err
		}
	}
	return _err
}
func VerifyPhoneCode(phone, code string) bool {
	redisCli := utils.GetRedis()
	res, err := redisCli.HGetAll(context.Background(), PhoneVerifyCodeCacheName+phone).Result()
	if err != nil {
		klog.Error(err)
		return false
	}
	if res["code"] == code {
		return true
	}
	klog.Errorf("code do not matched, code provided:%s actually is %s", code, res["code"])
	return false
}
